package com.lianxi.controller;

import cn.hutool.http.HtmlUtil;
import com.lianxi.dto.AjaxDto;
import com.lianxi.dto.ResultUtil;
import com.lianxi.es.Page;
import com.lianxi.pojo.News;
import com.lianxi.pojo.NewsQuery;
import com.lianxi.util.StringUtil;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.commons.lang3.StringUtils;
import org.apache.xmlbeans.impl.jam.internal.elements.PackageImpl;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.constraints.Max;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

@Controller
@RequestMapping("/es")
public class AnyangEsController {
    @Autowired
    private RestHighLevelClient client;

    @PostMapping("/list")
    @ResponseBody
    public AjaxDto userPage(Page page, NewsQuery newsQuery) throws IOException {


//        Page<News> newsPage = newsService.pageByQuery(page, newsQuery);
        SearchRequest request = new SearchRequest("newsinfos");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.filter(QueryBuilders.matchAllQuery());
        boolQueryBuilder.filter(QueryBuilders.termQuery("siteId","45001"));
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.from(1);
        request.source(sourceBuilder);
        SearchResponse response=client.search(request, RequestOptions.DEFAULT);

        //数据收集
        List<Map<String,Object>> data = new ArrayList<>();
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            data.add(sourceAsMap);
        }
        for (Map<String, Object> datum : data) {
            System.out.println(datum);
        }
        return ResultUtil.success();
    }

    @PostMapping("/list2")
    @ResponseBody
    public AjaxDto test(Page page, NewsQuery news){
        Page resp = resp(page, searchAnyang(page,news));
        List<News> datas = resp.getDatas();
//        for (News data : datas) {
//            System.out.println(data);
//        }
        return ResultUtil.success(page);
    }

    public Page resp(Page page, SearchResponse response){
        List<Map<String,Object>> data = new ArrayList<>();
        //获取命中的文档，处理结果集
        SearchHit[] hits = response.getHits().getHits();
        for(SearchHit s : hits){
            Map<String, Object> source = s.getSourceAsMap();
            source.put("_id",s.getId());
            //高亮处理
            Set<Map.Entry<String, HighlightField>> entries = s.getHighlightFields().entrySet();
            StringBuffer sb = new StringBuffer();
            for(Map.Entry<String, HighlightField> e : entries){
                String key = e.getKey();
                String value = Arrays.toString(e.getValue().fragments());
                //分词不连贯处理
                String highLightParts = value.substring(1,value.length()-1).trim().replaceAll("</span><span style='color:red;'>","");
                if (key.equals("name")) {
                    source.put(key, highLightParts);
                } else {
                    int addBeforeLen = HtmlUtil.escape(sb.toString()).length();
                    int addAfterLen = HtmlUtil.escape(sb.toString().concat(highLightParts)).length();
                    if (addBeforeLen <= 100 && addAfterLen <= 150) {
                        sb.append(highLightParts);
                    }
                }
            }
            String tmp = sb.toString();
            source.put("description",tmp.length()>0?tmp.concat("..."):tmp);
            data.add(source);
        }
        //处理页码
//        SearchResponse resp = response.getResponse();
        Long all = response.getHits().getTotalHits().value;
        Long pageTotal = all%page.getPageSize()==0?all/page.getPageSize():all/page.getPageSize()+1;
        page.setDatas(data);
        page.setTotalRow(all.intValue());
        page.setTotalPage(pageTotal.intValue());
        return page;
    }



    public SearchResponse toSearch(BoolQueryBuilder boolQueryBuilder,Page page)  {
        SearchRequest request = new SearchRequest("news");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.from((page.getPageNumber()-1)*page.getPageSize());
        sourceBuilder.size(page.getPageSize());
        sourceBuilder.sort("id", SortOrder.ASC);
        request.source(sourceBuilder);
        SearchResponse search=null;
        try {
            search = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {

            e.printStackTrace();
        }
        return search;
    }


    //查询条件
    public SearchResponse searchAnyang(Page page,NewsQuery query){
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(QueryBuilders.matchAllQuery());
        String keyword = query.getKeyword();
        String siteId = query.getSiteId();
        Integer smallType = query.getSmallType();
        if (StringUtils.isNotBlank(keyword)) {
            if (keyword.contains("_")){
               boolQueryBuilder.filter(QueryBuilders.termQuery("oldEntityId",keyword));
            }else {
               boolQueryBuilder.filter(QueryBuilders.wildcardQuery("title","*"+keyword+"*"));
            }
        }
        if (StringUtils.isNotBlank(siteId)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("siteId",siteId));
        }
        if (null != smallType) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("smallType",smallType));
        }

        SearchResponse response = toSearch(boolQueryBuilder,page);
        return response;
    }
    //精确查找
    public BoolQueryBuilder mytermQuery(Map<String,Object> map){
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.filter(QueryBuilders.matchAllQuery());
        //精确查找
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            if (entry.getValue()!=null)
            boolQueryBuilder.filter(QueryBuilders.termQuery(entry.getKey(),entry.getValue()));
        }
        return boolQueryBuilder;
    }

    //关键字模糊查询
    public BoolQueryBuilder mywildcardQuery(Map<String,Object> map,BoolQueryBuilder boolQueryBuilder){
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            if (entry.getValue()!=null)
                boolQueryBuilder.filter(QueryBuilders.wildcardQuery(entry.getKey(),"*"+entry.getValue()+"*"));
        }
        return boolQueryBuilder;
    }

    @PostMapping("/list3")
    @ResponseBody
    public AjaxDto test3(Page page, NewsQuery news){
        Map<String,Object> map=new HashMap<>();
//        map.put("siteid",news.getSiteId());
        page.setPageSize(10);
        page.setPageNumber(1);
        map.put("siteid",news.getSiteId());
        map.put("smallType",news.getSmallType());
        BoolQueryBuilder boolQueryBuilder =  mytermQuery(map).filter(QueryBuilders.matchAllQuery());
        SearchResponse response = toSearch(boolQueryBuilder, page);
        Page resp = resp(page, response);
        return ResultUtil.success(resp);
    }

    //更新某个字段,的某个值
    @PostMapping("/list4")
    public void  updateElastic() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest("news","JAdszIAB-W55AgHaESeP");
        updateRequest.doc(jsonBuilder()
                .startObject()
                .field("smallType", 2)
                .endObject());
        UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
    }

    //
}
